﻿using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using JM.JCY.BusinessEntity;
using JM.JCY.Proxy;
using System.Text.RegularExpressions;
using System.IO;
using System.Globalization;
using JM.JCY.Common;
using System.Web.Security;
using Microsoft.SharePoint.Administration;

namespace JM.JCY.SharePointComponent.UserManagement.EditUser
{
    public partial class EditUserUserControl : UserControl, ICallbackEventHandler
    {
        public int deptId { get; set; }
        public int jobTitleId { get; set; }
        public string deptName { get; set; }
        public string jobTitle { get; set; }
        public string IsMain { get; set; }
        public int _searchCriteriaLength { get; set; }
        static string JCYUrl = System.Configuration.ConfigurationManager.AppSettings["JCYUrl"].ToString();
        private static SPIisSettings _SPIisSettings;
        internal static SPIisSettings SPIisSettings
        {
            get
            {
                if (_SPIisSettings == null)
                {
                    SPSecurity.RunWithElevatedPrivileges(delegate()
                    {
                        _SPIisSettings = SPContext.Current.Site.WebApplication.GetIisSettingsWithFallback(SPContext.Current.Site.Zone);
                    });
                }

                return _SPIisSettings;
            }
        }

        internal static MembershipProvider MembershipProvider
        {
            get
            {
                return Membership.Providers[SPIisSettings.FormsClaimsAuthenticationProvider.MembershipProvider];
            }
        }

        internal static RoleProvider RoleProvider
        {
            get
            {
                return Roles.Providers[SPIisSettings.FormsClaimsAuthenticationProvider.RoleProvider];
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            string callbackReference = Page.ClientScript.GetCallbackEventReference(this, "arg", "ReceiveCallback", "context", false);
            string callbackScript = string.Format("function CallServer(arg,context){{ {0}  }}", callbackReference);
            Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer", callbackScript, true);
            this.ddlDept.SelectedIndex = 0;

            string removeUser = Request.Params.Get("__EVENTTARGET");
            if (!IsPostBack)
            {
                if (Request.QueryString["UserId"] != null)
                {
                    this.hfUserId.Value = Request.QueryString["UserId"].ToString();
                }

                using (UserManagementProxy proxy = new UserManagementProxy())
                {
                    DataSetUserManagement.T_DepartmentDataTable dtDept = proxy.GetAllDepartment();
                    this.ddlDept.DataSource = dtDept;

                  
                    ddlDept.DataTextField = "DeptName";
                    ddlDept.DataValueField = "ID";
                    ddlDept.DataBind();

                    cblDept.DataSource = dtDept;
                    cblDept.DataTextField = "DeptName";
                    cblDept.DataValueField = "ID";
                    cblDept.DataBind();
                }

                LoadData(Int32.Parse(this.hfUserId.Value));
            }
            if (removeUser != null && removeUser.IndexOf("DeleteUserById") > -1)
            {
                imgDelete_Click(null, null);
            }



        }

        protected void GridViewDeptList_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                ImageButton ib = (ImageButton)e.Row.Cells[2].FindControl("imgBtnDelete");
                ib.Attributes.Add("onclick", "javascript:return DeleteUserDept(" + ib.CommandArgument + ")");

            }
        }

        private void LoadData(int userId)
        {
            using (UserManagementProxy proxy = new UserManagementProxy())
            {
                var userDT = proxy.GetUserForSystem(userId);
                this.lblName.Text = userDT[0].UserName;
                if (!userDT[0].IsGenderNull())
                {
                    if (!string.IsNullOrEmpty(userDT[0].Gender))
                    {
                        this.rbGender.SelectedValue = userDT[0].Gender;
                    }
                }
                // do not need load department etc.
                var dt = proxy.GetUserDeptTitle(Int32.Parse(hfUserId.Value));
                this.GridViewDeptList.DataSource = dt;
                this.GridViewDeptList.DataBind();

                Session["UserEditDT"] = userDT;
                Session["EditGridViewSource"] = dt;

                UserInfoDataSet.T_DeptMgrDataTable dtDeptMgr = proxy.GetUserDeptMgr(this.lblName.Text);

                foreach (UserInfoDataSet.T_DeptMgrRow dr in dtDeptMgr.Rows)
                {
                    cblDept.Items.FindByValue(dr.DeptId.ToString()).Selected = true;
                }
            }
        }

        // call server back
        public string GetCallbackResult()
        {
            return RenderControl(GridViewDeptList);

        }

        //Realize ICallbackEventHandler member RaiseCallbackEvent
        public void RaiseCallbackEvent(string eventArgument)
        {

            string[] searchCriteria = new string[4];
            if (eventArgument.IndexOf('|') > 0)    //Click Search button to retrieve data
            {
                string[] r = eventArgument.Split('|');
                searchCriteria = Regex.Split(r[1], "@&@", RegexOptions.IgnoreCase);
                _searchCriteriaLength = searchCriteria.Length;
                if (searchCriteria.Length == 5)
                {
                    deptId = Int32.Parse(searchCriteria[1]);
                    jobTitleId = Int32.Parse(searchCriteria[2]);
                    deptName = searchCriteria[3];
                    jobTitle = searchCriteria[4];

                    var gvDT = (DepartmentTitleDataSet.T_DepartmentJobTitleDataTable)Session["EditGridViewSource"];
                    var gvDT2 = (DepartmentTitleDataSet.T_DepartmentJobTitleDataTable)gvDT.Copy();
                    if (gvDT.Rows.Count > 0)
                    {
                        bool isExist = false;
                        foreach (DepartmentTitleDataSet.T_DepartmentJobTitleRow row in gvDT.Rows)
                        {
                            if (jobTitleId == row.JobTitleId && deptName == row.DeptName)
                            {
                                isExist = true;
                                break;
                            }
                        }
                        if (!isExist)
                        {
                            DepartmentTitleDataSet.T_DepartmentJobTitleRow djRow = gvDT2.NewT_DepartmentJobTitleRow();
                            djRow.DeptId = deptId;
                            djRow.DeptName = deptName;
                            djRow.JobTitleId = jobTitleId;
                            djRow.JobTitle = jobTitle;
                            gvDT2.Rows.Add(djRow);
                            Session["EditGridViewSource"] = gvDT2.Copy();
                            this.GridViewDeptList.DataSource = gvDT2;
                            this.GridViewDeptList.DataBind();
                        }
                        else
                        {
                            this.GridViewDeptList.DataSource = gvDT;
                            this.GridViewDeptList.DataBind();
                        }

                    }
                    else
                    {
                        DepartmentTitleDataSet.T_DepartmentJobTitleRow djRow = gvDT.NewT_DepartmentJobTitleRow();
                        djRow.DeptId = deptId;
                        djRow.DeptName = deptName;
                        djRow.JobTitleId = jobTitleId;
                        djRow.JobTitle = jobTitle;
                        gvDT.Rows.Add(djRow);
                        Session["EditGridViewSource"] = gvDT.Copy();
                        this.GridViewDeptList.DataSource = gvDT.Copy();
                        this.GridViewDeptList.DataBind();
                    }
                }
                else if (searchCriteria.Length == 2)
                {
                    var gvDT = (DepartmentTitleDataSet.T_DepartmentJobTitleDataTable)Session["EditGridViewSource"];

                    int id = Convert.ToInt32(searchCriteria[1]);
                    gvDT.Rows.Remove(gvDT.FindByJobTitleId(id));

                    Session["EditGridViewSource"] = gvDT.Copy();
                    GridViewDeptList.DataSource = gvDT;
                    GridViewDeptList.DataBind();

                }

            }

        }

        private string RenderControl(Control control)
        {
            StringWriter writer1 = new StringWriter(CultureInfo.InvariantCulture);
            HtmlTextWriter writer2 = new HtmlTextWriter(writer1);

            control.RenderControl(writer2);
            writer2.Flush();
            writer2.Close();

            return writer1.ToString();
        }


        protected void imgSave_Click(object sender, ImageClickEventArgs e)
        {
            var _userId = Int32.Parse(this.hfUserId.Value);
            using (UserManagementProxy proxy = new UserManagementProxy())
            {
                // update user info
                var userDT = proxy.GetUserForSystem(_userId);
                if (userDT.Rows.Count > 0)
                {
                    userDT[0].Gender = this.rbGender.SelectedValue;
                    if (this.rbGender.SelectedValue == "男")
                        userDT[0].PhotoImagePath = JCYConstant.StaffProfile.DefaultPicturePathMan;
                    else
                        userDT[0].PhotoImagePath = JCYConstant.StaffProfile.DefaultPicturePathWoman;
                    userDT[0].Status = this.rblStatus.SelectedValue;
                    JCYUtility.UpdateCommonFields(userDT[0], "admin");
                    proxy.UpdateUserInfo(userDT);
                }

                // delete old data
                var oldUserDept = proxy.GetUserDeptByUserId(_userId);
                for (int i = 0; i < oldUserDept.Rows.Count; i++)
                {
                    oldUserDept.Rows[i]["IsDeleted"] = true;
                    proxy.UpdateUserDept(oldUserDept);

                    // remove user from old user group
                    var oldDept = proxy.GetDeptById(oldUserDept[i].DepartmentId, string.Empty);
                 
                    RemoveUserFromGroup(oldDept[0].DeptName);
                }
                var oldUserJobTitle = proxy.GetUserJobTiTleByUserId(_userId);
                for (int j = 0; j < oldUserJobTitle.Rows.Count; j++)
                {
                    oldUserJobTitle.Rows[j]["IsDeleted"] = true;
                    proxy.UpdateUserJobTitle(oldUserJobTitle);
                }

                // create new data
                var NewUserDeptDT = new DepartmentTitleDataSet.T_UserDepartmentDataTable();
                var NewUserJobTitleDT = new DepartmentTitleDataSet.T_UserJobTitleDataTable();
                DepartmentTitleDataSet.T_DepartmentJobTitleDataTable gvDT = (DepartmentTitleDataSet.T_DepartmentJobTitleDataTable)Session["EditGridViewSource"];

                foreach (DepartmentTitleDataSet.T_DepartmentJobTitleRow row in gvDT.Rows)
                {
                    DepartmentTitleDataSet.T_UserDepartmentRow userDeptRow = NewUserDeptDT.NewT_UserDepartmentRow();
                    userDeptRow.UserId = _userId;
                    userDeptRow.DepartmentId = row.DeptId;
                    userDeptRow.IsDeleted = false;
                    JCYUtility.UpdateCommonFields(userDeptRow, "admin");
                    NewUserDeptDT.Rows.Add(userDeptRow);

                    DepartmentTitleDataSet.T_UserJobTitleRow userJobTitleRow = NewUserJobTitleDT.NewT_UserJobTitleRow();
                    userJobTitleRow.UserId = Int32.Parse(this.hfUserId.Value);
                    userJobTitleRow.JobTitleId = row.JobTitleId;
                    userJobTitleRow.IsMain = true;
                    userJobTitleRow.IsDeleted = false;
                    JCYUtility.UpdateCommonFields(userJobTitleRow, "admin");
                    NewUserJobTitleDT.Rows.Add(userJobTitleRow);

                    // add user into group
                    DataSetUserManagement.T_DepartmentDataTable dept = proxy.GetDeptById(row.DeptId, string.Empty);
                    if (dept.Rows.Count > 0)
                    {
                        SPUser spUser = SPContext.Current.Web.EnsureUser(this.lblName.Text);
                        if (!IsExistUser(spUser, dept[0].DeptName))
                            AddUserToGroup(spUser, dept[0].DeptName);
                    }

                }

                proxy.UpdateUserDept(NewUserDeptDT);
                proxy.UpdateUserJobTitle(NewUserJobTitleDT);


                proxy.DeleteDeptMgrByUserName(this.lblName.Text);
                UserInfoDataSet.T_DeptMgrDataTable dtDeptMgr = new UserInfoDataSet.T_DeptMgrDataTable();
                foreach (ListItem li in this.cblDept.Items)
                {
                    if (li.Selected)
                    {
                        UserInfoDataSet.T_DeptMgrRow dr = dtDeptMgr.NewT_DeptMgrRow();
                        dr.UserId = _userId;
                        dr.UserName = this.lblName.Text;
                        dr.DeptId = Int32.Parse(li.Value);
                        dtDeptMgr.Rows.Add(dr);


                        SPUser spUser = SPContext.Current.Web.EnsureUser(this.lblName.Text);
                        string deptName = proxy.GetDepartmentTitleById(dr.DeptId).T_Department.Rows[0]["DeptName"].ToString();
                        AddUserToMgrGroup(spUser, deptName);
                    }
                }

                proxy.CreateDeptMgr(dtDeptMgr);


                ClearSession();
            }

            Response.Redirect("StaffMgr.aspx");
        }

        private void ClearSession()
        {
            Session["EditGridViewSource"] = null;
            Session.Remove("EditGridViewSource");

            Session["UserEditDT"] = null;
            Session.Remove("UserEditDT");
        }

        // update sharepoint related stuff
        public void RemoveUserFromGroup( string groupname)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
           {
               using (SPSite site = new SPSite(JCYUrl))
               {
                   using (SPWeb web = site.AllWebs[JCYConstant.SiteName.MyDept])
                   {
                       SPUser spUser = web.EnsureUser(this.lblName.Text);
                       if (IsExistUser(spUser, groupname))
                       {
                           web.AllowUnsafeUpdates = true;
                           web.SiteGroups[groupname].RemoveUser(spUser);
                           web.AllowUnsafeUpdates = false;
                       }
                   }
               }
           });
          
        
        }

        public void AddUserToGroup(SPUser user, string groupname)
        {
            try
            {
                  SPSecurity.RunWithElevatedPrivileges(delegate()
                  {
                      using (SPSite site = new SPSite(JCYUrl))
                      {
                          using (SPWeb web = site.AllWebs[JCYConstant.SiteName.MyDept])
                          {
                              if (!IsExistUser(user, groupname))
                              {
                                  web.AllowUnsafeUpdates = true;
                                  web.SiteGroups[groupname].AddUser(user);
                                  web.AllowUnsafeUpdates = false;
                              }
                          }
                      }
                  });
               
             
            }
            catch (Exception)
            {

                throw;
            }
        }

        public bool IsExistUser(SPUser user, string groupname)
        {
            bool exist = false;
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {

                using (SPSite site = new SPSite(JCYUrl))
                {
                    using (SPWeb web = site.AllWebs[JCYConstant.SiteName.MyDept])
                    {

                        SPUserCollection users = web.SiteGroups[groupname].Users;
                        foreach (SPUser userlist in users)
                        {

                            if (userlist.ToString().ToLower() == user.LoginName.ToLower())
                                exist = true;
                        }
                    }
                }
            });

            return exist;


        }

        private void DeleteUser(SPWeb web, int userId, string userName)
        {
            using (UserManagementProxy proxy = new UserManagementProxy())
            {
                // delete from user info
                //var userInfo = (DataSetUserManagement.T_UserInfoDataTable)Session["UserEditDT"];
                //userInfo[0].IsDeleted = true;
                //JCYUtility.UpdateCommonFields(userInfo[0], "admin");
                //proxy.UpdateUserInfo(userInfo);
                proxy.DeleteUserById(userId);


                var oldUserDept = proxy.GetUserDeptByUserId(userId);
                //SPUser spUser = web.EnsureUser(this.lblName.Text);
                // delete user from related groups
                foreach (DepartmentTitleDataSet.T_UserDepartmentRow row in oldUserDept.Rows)
                {
                    var oldDept = proxy.GetDeptById(row.DepartmentId, string.Empty);

                    RemoveUserFromGroup(oldDept[0].DeptName);
                }
                // delete user from site
                RemoveUserFromGroup(JCYConstant.MemberGroup);

                // delete personal doc
                SPSecurity.RunWithElevatedPrivileges(delegate()
               {

                   using (SPSite site = new SPSite(JCYUrl))
                   {
                       using (SPWeb webPersonal = site.AllWebs[JCYConstant.SiteName.PersonalSite])
                       {
                           webPersonal.AllowUnsafeUpdates = true;
                           var personDoc = webPersonal.Lists[userName];
                           webPersonal.Lists.Delete(personDoc.ID);
                           webPersonal.AllowUnsafeUpdates = false;
                       }
                   }
               });
               

                //delete user from FBA
                Membership.DeleteUser(userName, true);
            }

        }

        protected void imgDelete_Click(object sender, ImageClickEventArgs e)
        {
            DeleteUser(SPContext.Current.Web, Int32.Parse(this.hfUserId.Value), this.lblName.Text);
            Response.Redirect("StaffMgr.aspx");
        }

        public void AddUserToMgrGroup(SPUser user, string groupname)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite site = new SPSite(JCYUrl))
                {
                    using (SPWeb web = site.AllWebs[JCYConstant.SiteName.MyDept])
                    {
                        if (!IsExistUser(user, groupname))
                        {
                            web.AllowUnsafeUpdates = true;
                            web.SiteGroups[groupname].AddUser(user);
                            web.AllowUnsafeUpdates = false;
                        }
                    }
                }
            });
        }
    }
}
